#include "ui_newcharacterwizard.h"
#include "NewCharacterWizard.h"
#include "BaseAbilitiesWidget.h"
#include "ClassWidget.h"
#include "DetailsWidget.h"
#include "EquipmentWidget.h"
#include "FeatsWidget.h"
#include "PowersWidget.h"
#include "RaceWidget.h"
#include "SkillsWidget.h"

#include <DndData/DndData.h>
#include <DndData/CharacterData.h>
#include <Xml/XmlException.h>

#include <QTimer>
#include <QMessageBox>

const char *NewCharacterWizard::WIZARD_PAGE_TITLES[] = {
    QT_TRANSLATE_NOOP("Wizard page titles", "Determine Ability Scores"),
    QT_TRANSLATE_NOOP("Wizard page titles", "Select Race"),
    QT_TRANSLATE_NOOP("Wizard page titles", "Select and Refine Class"),
    QT_TRANSLATE_NOOP("Wizard page titles", "Choose Skills"),
    QT_TRANSLATE_NOOP("Wizard page titles", "Select Feats"),
    QT_TRANSLATE_NOOP("Wizard page titles", "Configure Powers"),
    QT_TRANSLATE_NOOP("Wizard page titles", "Buy Equipment"),
    QT_TRANSLATE_NOOP("Wizard page titles", "Add Details")
};

NewCharacterWizard::NewCharacterWizard(QWidget *parent)
    : QDialog(parent)
    , mWizard(new Ui::NewCharacterWizard())
    , mCharacterData(new CharacterData(tr("New Character")))
{
    QTimer::singleShot(0, this, SLOT(initialize()));
}

void NewCharacterWizard::initialize()
{
    mWizard->setupUi(this);
    mWizard->classComboBox->addItem(tr("Choose class"));
    for (int classIndex = 0; classIndex < DndData::NUM_CLASSES; ++classIndex)
    {
            mWizard->classComboBox->addItem(DndData::CLASS_NAMES[classIndex]);
    }
    mWizard->wizardPageNameLabel->setText(WIZARD_PAGE_TITLES[0]);
    QStackedWidget *sw = mWizard->stackedWidget;
    BaseAbilitiesWidget *w = new BaseAbilitiesWidget(mCharacterData, this);
    connect(mWizard->classComboBox, SIGNAL(currentIndexChanged(int)),
                    w, SLOT(updateToClass(int)));
    connect(mWizard->characterName, SIGNAL(textChanged(const QString &)),
            this, SLOT(setCharacterName(const QString &)));
    QWidget *page = sw->widget(0);
    while (page)
    {
        // clear out any spurious pages placed in by designer
        sw->removeWidget(page);
        page = sw->widget(0);
    }
    sw->addWidget(w);
    sw->addWidget(new RaceWidget(mCharacterData, this));

    ClassWidget *cw = new ClassWidget(mCharacterData, this);
    connect(mWizard->classComboBox, SIGNAL(currentIndexChanged(QString)),
            cw, SLOT(updateToClass(const QString &)));
    sw->addWidget(cw);
    sw->addWidget(new SkillsWidget(mCharacterData, this));
    sw->addWidget(new FeatsWidget(mCharacterData, this));
    sw->addWidget(new PowersWidget(mCharacterData, this));
    sw->addWidget(new EquipmentWidget(mCharacterData, this));
    sw->addWidget(new DetailsWidget(mCharacterData, this));
}

NewCharacterWizard::~NewCharacterWizard()
{
}

void NewCharacterWizard::setCharacterName(const QString &name)
{
    mCharacterData->setTitle(name);
}

void NewCharacterWizard::selectPage(NewCharacterWizard::WizardPages page)
{
    mWizard->stackedWidget->setCurrentIndex(page);
    mWizard->wizardPageNameLabel->setText(WIZARD_PAGE_TITLES[page]);
    mWizard->backPushButton->setEnabled(page > AbilityScores);
    mWizard->nextPushButton->setEnabled((page < AddDetails));
    switch (page)
{
        case AbilityScores:
            mWizard->classComboBox->setEnabled(true);
            mWizard->classComboBox->setToolTip(tr(
                            "Optimize abilities for a chosen class."));
            break;
        case SelectRace:
            mWizard->classComboBox->setEnabled(true);
            mWizard->classComboBox->setToolTip(tr(
                            "Optimize race for a chosen class."));
            break;
        case SelectClass:
            mWizard->classComboBox->setEnabled(true);
            mWizard->classComboBox->setToolTip(tr(
                            "Confirm the class for your character."));
            break;
        case ChooseSkills:
            mWizard->classComboBox->setEnabled(false);
            break;
        case SelectFeats:
            mWizard->classComboBox->setEnabled(false);
            break;
        case ConfigurePowers:
            mWizard->classComboBox->setEnabled(false);
            break;
        case BuyEquipment:
            mWizard->classComboBox->setEnabled(false);
            break;
        case AddDetails:
            mWizard->classComboBox->setEnabled(false);
            break;
    }
}

void NewCharacterWizard::on_backPushButton_clicked(bool)
{
    int index = mWizard->stackedWidget->currentIndex();
    if (index > 0)
            selectPage(static_cast<WizardPages>(index - 1));
}

void NewCharacterWizard::on_nextPushButton_clicked(bool)
{
    int index = mWizard->stackedWidget->currentIndex();
    if (index < (mWizard->stackedWidget->count() - 1))
            selectPage(static_cast<WizardPages>(index + 1));
}

void NewCharacterWizard::on_buttonBox_accepted()
{
    try
    {
        mCharacterData->saveToXml();
        mDataSaveName = mCharacterData->title();
    }
    catch (XmlException e)
    {
        QMessageBox::critical(this, tr("Could not save to XML"), e.message());
    }
    done(QDialog::Accepted);
}
